package com.gd.iot.energy.service.systemadmin.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gd.iot.energy.code.ResponseCode;
import com.gd.iot.energy.consts.SystemConsts;
import com.gd.iot.energy.dao.systemadmin.HouseholdPOMapper;
import com.gd.iot.energy.exception.MyException;
import com.gd.iot.energy.po.systemadmin.HouseholdPO;
import com.gd.iot.energy.pojo.common.vo.ColumnVO;
import com.gd.iot.energy.pojo.common.vo.PageVO;
import com.gd.iot.energy.pojo.systemadmin.dto.AreaOrganizationSaveDTO;
import com.gd.iot.energy.pojo.systemadmin.dto.HouseholdSaveDTO;
import com.gd.iot.energy.pojo.systemadmin.vo.AreaOrganizationVO;
import com.gd.iot.energy.pojo.systemadmin.vo.EnumVO;
import com.gd.iot.energy.pojo.systemadmin.vo.HouseholdPageVO;
import com.gd.iot.energy.pojo.systemadmin.vo.HouseholdVO;
import com.gd.iot.energy.service.systemadmin.AreaOrganizationService;
import com.gd.iot.energy.service.systemadmin.HouseholdService;
import com.gd.iot.energy.util.CustomBeanUtils;
import com.gd.iot.energy.util.CustomColumnUtil;
import com.gd.iot.energy.util.CustomStrUtil;
import com.gd.iot.energy.util.EnergyTypeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class HouseholdServiceImpl extends ServiceImpl<HouseholdPOMapper, HouseholdPO> implements HouseholdService {
    public static final String HOUSEHOLD_SERIALNUM_INITVALUE = "100000001";
    @Resource
    private HouseholdPOMapper householdPOMapper;

    @Autowired
    private AreaOrganizationService areaOrganizationService;

    /**
     * 表头文件
     */
    private static final String HOURSEHOLD_LIST_COLUMN_FILE_NAME = "systemadmin/household_list.column";

    @Override
    public List<HouseholdVO> getHouseHoldVOs(Long areaOrg, String householdName) {
        QueryWrapper<HouseholdPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_del", SystemConsts.BooleanEnum.FALSE.value);
        if (StrUtil.isNotBlank(householdName)) {
            queryWrapper.like("household_name", householdName);
        }

        if (areaOrg != null) {
            List<Long> allChildAreaIds = areaOrganizationService.getAllChildAreaIds(BigDecimal.valueOf(areaOrg).intValue());
            if (CollUtil.isNotEmpty(allChildAreaIds)) {
                queryWrapper.in("area_org", allChildAreaIds);
            }
        }

        EnergyTypeUtil.injectEnergyTypeWrapper(queryWrapper);
        List<HouseholdPO> householdPOS = householdPOMapper.selectList(queryWrapper);
        List<HouseholdVO> householdVOS = new ArrayList<>(householdPOS.size());
        CustomBeanUtils.convertPojo(householdPOS,householdVOS,HouseholdVO.class);
        return householdVOS;
    }

    @Override
    public PageVO<HouseholdPageVO> getHouseHoldPageVOs(Long areaOrg, Integer filterType, String filterValue,
                                                       Integer pageSize, Integer pageNo, String orderColumn, String orderType) {
        IPage<HouseholdPO> page = new Page<>(pageNo, pageSize);
        QueryWrapper<HouseholdPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_del", SystemConsts.BooleanEnum.FALSE.value);

        if (!SystemConsts.HouseholdFilter.ALL.value.equals(filterType)) {
            if (SystemConsts.HouseholdFilter.HOURSE_NAME.value.equals(filterType) && StrUtil.isNotBlank(filterValue)) {
                queryWrapper.like("household_name", filterValue.trim());
            } else if (SystemConsts.HouseholdFilter.HOURSE_NUMBER.value.equals(filterType) && StrUtil.isNotBlank(filterValue)) {
                queryWrapper.like("household_serialnumber", filterValue.trim());
            } else if (SystemConsts.HouseholdFilter.ENABLED.value.equals(filterType) && StrUtil.isNotBlank(filterValue)) {
                queryWrapper.like("household_phone", filterValue.trim());
            }
        }

        if (areaOrg != null) {
            List<Long> allChildAreaIds = areaOrganizationService.getAllChildAreaIds(BigDecimal.valueOf(areaOrg).intValue());
            if (CollUtil.isNotEmpty(allChildAreaIds)) {
                queryWrapper.in("area_org", allChildAreaIds);
            }
        }

        if (StrUtil.isNotBlank(orderColumn) && StrUtil.isNotBlank(orderType)) {
            orderColumn = CustomStrUtil.humpToLine(orderColumn);
            queryWrapper.orderBy(true, orderType.equals(SystemConsts.OrderType.ASC.value), orderColumn);
        }
        EnergyTypeUtil.injectEnergyTypeWrapper(queryWrapper);
        IPage<HouseholdPO> householdPOIPage = householdPOMapper.selectPage(page, queryWrapper);
        PageVO<HouseholdPageVO> pageVO = new PageVO<>();
        pageVO.setPageSize(pageSize);
        pageVO.setPageNum(pageNo);
        List<HouseholdPageVO> treePageVOS = convertToHouseholdPageVOList(householdPOIPage.getRecords(), pageSize, pageNo);
        pageVO.setData(treePageVOS);
        pageVO.setTotal(householdPOIPage.getTotal());
        pageVO.setPages(householdPOIPage.getPages());

        //表头
        List<ColumnVO> columns = CustomColumnUtil.getColumn(HOURSEHOLD_LIST_COLUMN_FILE_NAME);
        pageVO.setColumns(columns);
        return pageVO;
    }

    /**
     * 对象转换
     *
     * @param records
     * @return
     */
    private List<HouseholdPageVO> convertToHouseholdPageVOList(List<HouseholdPO> records, Integer pageSize, Integer pageNo) {
        List<AreaOrganizationVO> areaOrganizationVOs = areaOrganizationService.getAreaOrganizationVOs();
        Map<Long, String> collect = areaOrganizationVOs.stream().collect(
                Collectors.toMap(AreaOrganizationVO::getId, AreaOrganizationVO::getName, (key1, key2) -> key2));
        List<HouseholdPageVO> res = new ArrayList<>(records.size());
        HouseholdPageVO householdPageVO;

        int i = pageSize * (pageNo - 1) + 1;
        for (HouseholdPO record : records) {
            householdPageVO = new HouseholdPageVO();
            householdPageVO.setSerialNum(i);
            householdPageVO.setId(record.getId());
            householdPageVO.setHouseholdName(record.getHouseholdName());
            householdPageVO.setHouseholdSerialnumber(record.getHouseholdSerialnumber());
            householdPageVO.setAreaOrgName(collect.get(record.getAreaOrg()));
            householdPageVO.setHouseholdPhone(record.getHouseholdPhone());
            householdPageVO.setHouseholdAddress(record.getHouseholdAddress());
            res.add(householdPageVO);
            i++;
        }
        return res;
    }

    @Override
    @Transactional
    public Long add(HouseholdSaveDTO houseHoldSaveDTO) {
        if (houseHoldSaveDTO.getHouseholdName() == null) {
            throw new MyException(ResponseCode.PARAMETER_REQUIRED);
        }

        HouseholdPO householdPO = new HouseholdPO();
        householdPO.setCompanyId(0L);
        householdPO.setCreateDate(new Date());
        householdPO.setEnergyType(SystemConsts.EnergyTypeEnum.WATER.value);
        householdPO.setIsDel(SystemConsts.BooleanEnum.FALSE.value);
        householdPO.setModifyDate(new Date());
        householdPO.setOperatorId(1L);

        householdPO.setHouseholdAddress(houseHoldSaveDTO.getHouseholdAddress());
        householdPO.setHouseholdFee(houseHoldSaveDTO.getHouseholdFee());
        householdPO.setHouseholdName(houseHoldSaveDTO.getHouseholdName());
        householdPO.setHouseholdPassword(houseHoldSaveDTO.getHouseholdPassword());
        householdPO.setHouseholdPhone(houseHoldSaveDTO.getHouseholdPhone());
//        householdPO.setHouseholdSerialnumber(houseHoldSaveDTO.getHouseholdSerialnumber());
        String maxSerialnum = householdPOMapper.getMaxSerialnum();
        maxSerialnum = maxSerialnum == null ? HOUSEHOLD_SERIALNUM_INITVALUE : maxSerialnum;
        int serialnum = Integer.parseInt(maxSerialnum) + 1;
        householdPO.setHouseholdSerialnumber(String.valueOf(serialnum));
        householdPO.setHouseholdWarnMoney(houseHoldSaveDTO.getHouseholdWarnMoney());
        householdPO.setAreaOrg(houseHoldSaveDTO.getAreaOrg());

        householdPOMapper.insert(householdPO);
        return householdPO.getId();
    }

    @Override
    public boolean update(HouseholdSaveDTO houseHoldSaveDTO) {
        if (houseHoldSaveDTO.getHouseholdName() == null ||
                StrUtil.isBlank(houseHoldSaveDTO.getHouseholdSerialnumber())) {
            throw new MyException(ResponseCode.PARAMETER_REQUIRED);
        }

        HouseholdPO householdPO = new HouseholdPO();
        householdPO.setId(houseHoldSaveDTO.getId());
        householdPO.setModifyDate(new Date());
        householdPO.setOperatorId(1L);

        householdPO.setHouseholdAddress(houseHoldSaveDTO.getHouseholdAddress());
        householdPO.setHouseholdFee(houseHoldSaveDTO.getHouseholdFee());
        householdPO.setHouseholdName(houseHoldSaveDTO.getHouseholdName());
        householdPO.setHouseholdPassword(houseHoldSaveDTO.getHouseholdPassword());
        householdPO.setHouseholdPhone(houseHoldSaveDTO.getHouseholdPhone());
        householdPO.setHouseholdSerialnumber(houseHoldSaveDTO.getHouseholdSerialnumber());
        householdPO.setHouseholdWarnMoney(houseHoldSaveDTO.getHouseholdWarnMoney());
        householdPO.setAreaOrg(houseHoldSaveDTO.getAreaOrg());

        householdPOMapper.updateById(householdPO);
        return true;
    }

    @Override
    public boolean delete(List<Integer> ids) {
        if(CollUtil.isEmpty(ids)){
            throw new MyException(ResponseCode.PARAMETER_REQUIRED);
        }

        //供应商表逻辑删除
        QueryWrapper<HouseholdPO> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("id", ids);
        EnergyTypeUtil.injectEnergyTypeWrapper(queryWrapper);
        HouseholdPO householdPO = new HouseholdPO();
        householdPO.setIsDel(SystemConsts.BooleanEnum.TRUE.value);
        int num = householdPOMapper.update(householdPO,queryWrapper);

        return num > 0;
    }

    @Override
    public HouseholdSaveDTO getHouseHold(Integer id) {
        HouseholdPO householdPO = householdPOMapper.selectById(id);
        if(householdPO==null||SystemConsts.BooleanEnum.TRUE.value.equals(householdPO.getIsDel())){
            throw new MyException(ResponseCode.RECORD_NOT_EXIST);
        }

        HouseholdSaveDTO householdSaveDTO = new HouseholdSaveDTO();
        householdSaveDTO.setId(householdPO.getId());
        householdSaveDTO.setHouseholdName(householdPO.getHouseholdName());
        householdSaveDTO.setHouseholdSerialnumber(householdPO.getHouseholdSerialnumber());
        householdSaveDTO.setAreaOrg(householdPO.getAreaOrg());
        AreaOrganizationSaveDTO areaOrganization = areaOrganizationService.getAreaOrganization(BigDecimal.valueOf(householdPO.getAreaOrg()).intValue());
        householdSaveDTO.setAreaOrgName(areaOrganization==null?"":areaOrganization.getName());
        householdSaveDTO.setHouseholdAddress(householdPO.getHouseholdAddress());
        householdSaveDTO.setHouseholdPhone(householdPO.getHouseholdPhone());
        householdSaveDTO.setHouseholdPassword(householdPO.getHouseholdPassword());
        householdSaveDTO.setHouseholdWarnMoney(householdPO.getHouseholdWarnMoney());
        householdSaveDTO.setHouseholdFee(householdPO.getHouseholdFee());

        return householdSaveDTO;
    }

    @Override
    public Map<String, List<EnumVO>> getEnums() {
        Map<String, List<EnumVO>> resultMap = new HashMap<>();

        List<EnumVO> household = new ArrayList<>();
        for (SystemConsts.HouseholdFilter value : SystemConsts.HouseholdFilter.values()) {
            EnumVO vo = new EnumVO();
            vo.setValue(value.value);
            vo.setValueName(value.valueName);
            household.add(vo);
        }

        resultMap.put("household", household);
        return resultMap;
    }
}
